package com.vhall.component.service.rbac.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.vhall.component.dao.rbac.RbacRoleAccessMapper;
import com.vhall.component.entity.rbac.RoleAccessEntity;
import com.vhall.component.entity.rbac.vo.*;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.service.rbac.RbacAccessService;
import com.vhall.component.service.rbac.RbacRoleAccessService;
import com.vhall.component.service.rbac.RbacRoleService;
import com.vhall.component.service.rbac.constant.AccessConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dalong
 * @date 2021-05-11 16:25
 */
@Service
public class RbacRoleAccessServiceImpl implements RbacRoleAccessService {

    @Autowired
    private RbacRoleService roleService;

    @Autowired
    private RbacRoleAccessMapper roleAccessMapper;

    @Autowired
    private RbacAccessService accessService;

    @Override
    public List<RoleAccessEntity> getListByRoleIdAppId(Integer roleId, String appId) {
        List<RoleAccessEntity> roleAccessEntities = new ArrayList<>();
        // 查询角色信息
        RoleVO roleEntity = roleService.getInfo(roleId);
        if (roleEntity == null) {
            return roleAccessEntities;
        }
        // 查询权限列表
        LambdaQueryWrapper<RoleAccessEntity> where = Wrappers.lambdaQuery();
        where.eq(RoleAccessEntity::getRoleId, roleId)
                .eq(RoleAccessEntity::getStatus, AccessConstant.NORMAL_STATUS)
                .isNull(RoleAccessEntity::getDeletedAt);
        List<RoleAccessEntity> roleAccessEntityList = roleAccessMapper.selectList(where);
        if (roleAccessEntityList != null) {
            roleAccessEntities = roleAccessEntityList;
        }
        return roleAccessEntities;
    }

    @Override
    public List<Integer> getList(UserGetAccessListReqVO reqVO) {
        return accessService.getAccessListByRoleId(reqVO.getRoleName());
    }

    /**
     * 加事务？
     *
     * @param reqVO
     * @return
     */
    @Override
    public boolean batchCreate(RoleAddAccessReqVO reqVO) {
        // check role id
        RoleVO roleVO = roleService.getInfoById(reqVO.getRoleId());
        if (roleVO == null) {
            throw new BusinessException(BizErrorCode.BIZ_ROLE_NOT_EXIST);
        }

        JSONArray accessIds;
        try {
            accessIds = JSONObject.parseArray(reqVO.getAccessId());
        } catch (Exception e) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
        List<Integer> idList = accessIds.toJavaList(Integer.class);
        boolean checkResult = accessService.checkAccessId(idList);
        if (!checkResult) {
            throw new BusinessException(BizErrorCode.AUTH_ACCESS_EMPTY);
        }
        // create
        for (Integer accessId : idList) {
            RoleAccessEntity roleAccessEntity = getInfoByRoleIdAccessId(reqVO.getRoleId(), accessId);
            if (roleAccessEntity == null) {
                roleAccessEntity = new RoleAccessEntity();
                roleAccessEntity.setAccessId(accessId);
                roleAccessEntity.setRoleId(reqVO.getRoleId());
                roleAccessMapper.insert(roleAccessEntity);
            } else {
                if (AccessConstant.DEL_STATUS.equals(roleAccessEntity.getStatus())) {
                    // update
                    roleAccessEntity.setStatus(AccessConstant.NORMAL_STATUS);
                    roleAccessEntity.setDeletedAt(null);
                    roleAccessEntity.setUpdatedAt(LocalDateTime.now());
                    roleAccessMapper.updateById(roleAccessEntity);
                }
            }
        }
        return true;
    }

    @Override
    public boolean batchDelete(RoleDeleteAccessReqVO reqVO) {
        List<String> accessIdList;
        try {
            accessIdList = JSONObject.parseArray(reqVO.getAccessId(), String.class);
        } catch (Exception e) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
        LambdaUpdateWrapper<RoleAccessEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(RoleAccessEntity::getRoleId, reqVO.getRoleId())
                .in(RoleAccessEntity::getAccessId, accessIdList)
                .set(RoleAccessEntity::getStatus, AccessConstant.DEL_STATUS)
                .set(RoleAccessEntity::getDeletedAt, LocalDateTime.now());
        roleAccessMapper.update(null, updateWrapper);
        return true;
    }

    @Override
    public List<RoleInfoRspVO> getAccessListById(RoleInfoReqVO reqVO) {
        return roleAccessMapper.getListWithAccess(reqVO.getAppId(), reqVO.getRoleId(), AccessConstant.NORMAL_STATUS);
    }

    /**
     * 查询详情
     *
     * @param roleId
     * @param accessId
     * @return
     */
    private RoleAccessEntity getInfoByRoleIdAccessId(Integer roleId, Integer accessId) {
        // 查询权限列表
        LambdaQueryWrapper<RoleAccessEntity> where = Wrappers.lambdaQuery();
        where.eq(RoleAccessEntity::getRoleId, roleId)
                .eq(RoleAccessEntity::getAccessId, accessId);
        return roleAccessMapper.selectOne(where);
    }


}
